const PEDDING = "PEDDING",
  FULFILLED = "FULFILLED",
  REJECTED = "REJECTED";
class MyPromise {
  constructor(handle) {
    this.status = PEDDING;
    this.fulfilledQueues = [];
    this.rejectedQueues = [];
    handle(this.resolve.bind(this), this.reject.bind(this));
  }
  resolve(value) {
    setTimeout(() => {
      if (this.status !== PEDDING) return;
      this.status = FULFILLED;
      let cb;
      while ((cb = this.fulfilledQueues.shift())) {
        cb(value);
      }
    }, 0);
  }
  reject(err) {
    setTimeout(() => {
      if (this.status !== PEDDING) return;
      this.status = REJECTED;
      let cb;
      while ((cb = this.rejectedQueues.shift())) {
        cb(err);
      }
    }, 0);
  }
  then(onFulfilled, onRejected) {
    return new MyPromise((nextResolve, nextReject) => {
      const newOnFulfilled = (value) => {
        const res = onFulfilled(value);
        if (res instanceof MyPromise) {
          res.then((value) => {
            nextResolve(value);
          });
        } else {
          nextResolve(res);
        }
      };
      const newOnRejected = (err) => {
        if (typeof onRejected === "function") {
          const res = onRejected(err);
          if (res instanceof MyPromise) {
            res.then((err) => {
              nextReject(err);
            });
          } else {
            nextReject(res);
          }
        }
      };

      const status = this.status;
      switch (status) {
        case PEDDING:
          this.fulfilledQueues.push(newOnFulfilled);
          this.rejectedQueues.push(newOnRejected);
          break;
        case FULFILLED:
          break;
        case REJECTED:
          break;
        default:
          break;
      }
    });
  }
}

module.exports = MyPromise;
